package com.devilvan.betrice.jpxgmn.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.devilvan.betrice.annotation.BetriceRunTime;
import com.devilvan.betrice.common.BetriceResultCode;
import com.devilvan.betrice.common.BetriceResultVo;
import com.devilvan.betrice.jpxgmn.common.JpxgmnConstant;
import com.devilvan.betrice.jpxgmn.dto.JpxgmnDetailDto;
import com.devilvan.betrice.jpxgmn.mapper.JpxgmnHeaderMapper;
import com.devilvan.betrice.jpxgmn.po.JpxgmnDetailPo;
import com.devilvan.betrice.jpxgmn.po.JpxgmnHeaderPo;
import com.devilvan.betrice.jpxgmn.service.JpxgmnDetailService;
import com.devilvan.betrice.jpxgmn.mapper.JpxgmnDetailMapper;
import com.devilvan.betrice.jpxgmn.repository.JpxgmnDetailRepository;
import com.devilvan.betrice.jpxgmn.vo.JpxgmnDetailVo;
import com.devilvan.betrice.request.component.JsoupComponent;
import com.devilvan.betrice.util.UEmpty;
import com.devilvan.betrice.util.UString;
import com.devilvan.betrice.util.UCopy;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author Evad.Wu
 * @Description JPXGMN-明细信息表 业务逻辑类
 * @date 2022-11-16
 */
@Slf4j
@Service
public class JpxgmnDetailServiceImpl extends ServiceImpl<JpxgmnDetailMapper, JpxgmnDetailPo> implements JpxgmnDetailService {
    @Resource(name = "jsoupComponent")
    private JsoupComponent jsoupComponent;
    @Resource(name = "transactionTemplate")
    private TransactionTemplate transactionTemplate;

    @Resource(name = "jpxgmnDetailRepository")
    private JpxgmnDetailRepository jpxgmnDetailRepository;
    @Resource(name = "jpxgmnHeaderMapper")
    private JpxgmnHeaderMapper jpxgmnHeaderMapper;

    @Override
    public CompletableFuture<BetriceResultVo<JpxgmnDetailPo>> doJpxgmnDetailRequest(String url, String keyword, Map<String, String> subHeader) {
        BetriceResultVo<JpxgmnDetailPo> betriceResultVo = new BetriceResultVo<>();
        // 通过完整URL提取出对应的枚举类型
        JpxgmnConstant jpxgmnConstant = JpxgmnConstant.getInstanceByUrlPrefix(url);
        String jpxgmnConstantUrl = jpxgmnConstant.getUrl();
        subHeader.put("referer", jpxgmnConstantUrl);
        // 查询HEADER表中未采集明细的数据
        Page<JpxgmnHeaderPo> headerIsNotCrawl = jpxgmnHeaderMapper.findHeaderIsNotCrawl(keyword, new Page<>(1, 3));
        List<JpxgmnHeaderPo> jpxgmnHeaderPoList = headerIsNotCrawl.getRecords();
        String httpGetUrl = UEmpty.isNotEmpty(keyword) ? UString.generateHttpParamUrl(url, Map.of("keyword", keyword)) : url;
        for (JpxgmnHeaderPo jpxgmnHeaderPo : jpxgmnHeaderPoList) {
            doJpxgmnDetailExecutor(jpxgmnHeaderPo, subHeader, jpxgmnConstantUrl, httpGetUrl);
        }
        betriceResultVo.result(BetriceResultCode.SUCCESS_200, "操作成功！");
        return CompletableFuture.completedFuture(betriceResultVo);
    }

    @BetriceRunTime
    @Async(value = "threadPoolExecutor")
    public void doJpxgmnDetailExecutor(JpxgmnHeaderPo jpxgmnHeaderPo, Map<String, String> subHeader, String jpxgmnConstantUrl, String httpGetUrl) {
        String detailUrl = jpxgmnHeaderPo.getUrl();
        String pid = jpxgmnHeaderPo.getPid();
        Element body = jsoupComponent.getBody(detailUrl, subHeader);
        // 获取总页数
        Elements pageElement = body.select("div.pagination:nth-child(1)>ul>a");
        // 删除最后一个'下一页'
        if (pageElement.size() < 1) {
            jpxgmnHeaderPo.setLogicDel(true);
            jpxgmnHeaderMapper.updateById(jpxgmnHeaderPo);
            return;
        } else {
            pageElement.remove(pageElement.size() - 1);

        }
        List<JpxgmnDetailVo> jpxgmnDetailVoList = new CopyOnWriteArrayList<>();
        String lastRefererLink = null;
        for (Element currentPage : pageElement) {
            String currentLink = jpxgmnConstantUrl + currentPage.attr("href");
            // 分页请求，每次都要带上上一页的URL
            if (UEmpty.isEmpty(lastRefererLink)) {
                lastRefererLink = httpGetUrl;
            }
            subHeader.put("referer", lastRefererLink);
            Element innerBody = jsoupComponent.getBody(currentLink, subHeader);
            Elements imgList = innerBody.select("article.article-content>p>img");
            for (Element img : imgList) {
                String picLink = img.attr("src").replaceFirst("uploadfile", "Uploadfile");
                JpxgmnDetailVo jpxgmnDetailVo = new JpxgmnDetailVo();
                jpxgmnDetailVo.setPid(pid);
                String pJpmn5 = jpxgmnConstantUrl.replace("www", "p");
                jpxgmnDetailVo.setPicUrl(pJpmn5 + picLink);
                jpxgmnDetailVoList.add(jpxgmnDetailVo);
            }
            lastRefererLink = currentLink;
        }
        List<JpxgmnDetailDto> jpxgmnDetailDtoList = UCopy.fullCopyCollections(jpxgmnDetailVoList, JpxgmnDetailDto.class);
        transactionTemplate.execute(status -> {
            this.saveUpdateBatch(jpxgmnDetailDtoList);
            // 修改header的状态
            jpxgmnHeaderPo.setLogicDel(true);
            jpxgmnHeaderMapper.updateById(jpxgmnHeaderPo);
            return null;
        });
    }

    @Override
    public JpxgmnDetailPo saveUpdate(JpxgmnDetailDto jpxgmnDetailDto) {
        JpxgmnDetailPo jpxgmnDetailPo = new JpxgmnDetailPo();
        UCopy.fullCopy(jpxgmnDetailDto, jpxgmnDetailPo);
        return jpxgmnDetailRepository.saveAndFlush(jpxgmnDetailPo);
    }

    @Override
    public List<JpxgmnDetailPo> saveUpdateBatch(List<JpxgmnDetailDto> list) {
        List<JpxgmnDetailPo> jpxgmnDetailPoList = UCopy.fullCopyCollections(list, JpxgmnDetailPo.class);
        return jpxgmnDetailRepository.saveAllAndFlush(jpxgmnDetailPoList);
    }

    @Override
    public boolean updateBatch(List<JpxgmnDetailPo> list) {
        return this.updateBatchById(list);
    }

    @Override
    public void updatePicUrlToUpper() {
        List<JpxgmnDetailPo> list = this.list();
        List<JpxgmnDetailPo> poList = list.stream().peek(m -> {
            String replace = m.getPicUrl().replace("uploadfile", "Uploadfile");
            m.setPicUrl(replace);
        }).toList();
        this.updateBatchById(poList);
    }


}
